<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <link rel="stylesheet" href="./assets/global.css" />
  <style>
    #monster {
      width: 400px;
      height: 400px;
    }
  </style>
</head>

<body>
  <canvas id="monster"></canvas>
  <script type="module">
    import { Animation } from "https://gcore.jsdelivr.net/npm/@3r/tool/lib/animation.js";
    import { Randoms } from "https://gcore.jsdelivr.net/npm/@3r/tool/lib/randoms.js";
    /** @type {HTMLCanvasElement} */
    let canvas = document.querySelector("#monster");
    let ctx = canvas.getContext("2d");
    let width = canvas.clientWidth;
    let height = canvas.clientHeight;
    canvas.width = width;
    canvas.height = height;

    // 像素类
    class Pixel {
      constructor(x, y, data) {
        this.x = x;
        this.y = y;
        this.tx = 0;
        this.ty = 0;
        this.data = data;
      }

      setAlpha(a) {
        for (let i = 0; i < this.data.data.length; i += 4) {
          this.data.data[i + 3] = ~~(a * 255);
        }
      }
    }

    let pixels = [];
    let img = new Image();
    img.src = "./assets/monster/golza.jpg";
    img.onload = () => {
      ctx.drawImage(img, 100, 100, 200, 200);
      let h = 200;
      let w = 200;
      let s = 5; // 获取图片像素尺寸
      for (let y = 0; y < h; y += s) {
        for (let x = 0; x < w; x += s) {
          let data = ctx.getImageData(100 + x, 100 + y, s, s);
          let pixel = new Pixel(x, y, data);
          pixels.push(pixel);
        }
      }
    };

    let timestemp = 0;  // 时间戳
    let duration = 0.5; // 破碎时间
    // 点击
    canvas.addEventListener("click", (ev) => {
      timestemp = +new Date();
      for (let i = 0; i < pixels.length; i++) {
        const pixel = pixels[i];
        // 方向归一化
        let tx = (pixel.x - 100) / 200;
        let ty = (pixel.y - 100) / 200;
        // 随机需要移动的位置
        pixel.tx = tx * Randoms.int(300, 800);
        pixel.ty = ty * Randoms.int(300, 800);
      }
      requestAnimationFrame(render);
    });

    // 渲染
    function render() {
      let now = +new Date();
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      if (now - timestemp > 1000 * duration) return; // 超出时间移除
      let timeProportion = (now - timestemp) / (1000 * duration); // 时间比例
      let proportion = Animation.easeOut(timeProportion); // 完成比例
      for (let i = 0; i < pixels.length; i++) {
        const pixel = pixels[i];
        let x = pixel.tx * proportion + 200;
        let y = pixel.ty * proportion + 200;
        pixel.setAlpha(1 - timeProportion);
        if (x < 0 && y < 0) continue;
        ctx.putImageData(pixel.data, x, y);
      }
      requestAnimationFrame(render);
    }
  </script>
</body>

</html>